package com.jiang.mylibrary;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Scroller;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by peter on 2016/8/12.
 */
public class WheelView extends ViewGroup {

    private static final int SNAP_VELOCITY = 5000;

    private List<String> mDatas = new ArrayList<>();//数据
    private int mVisibCount = 3;//可视个数
    private Scroller mScroller;
    private GestureDetector detector;
    private int mCacheSizze = 2;//缓存个数
    private float textSize = 40;//文字的大小
    private int textColor = Color.BLACK;//文字颜色
    private int mSelectedItemIndex = 0;//选中项索引
    private int mHeight;//不是容器高度,而是整个高度
    private VelocityTracker velocityTracker;
    private float mRatioX = -45;

    public WheelView(Context context) {
        super(context);
    }

    public WheelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context, new AccelerateDecelerateInterpolator());
        detector = new GestureDetector(context, gestureListener);
    }

    public WheelView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 初始化
     */
    public void init() {
        int count = mDatas.size();
        this.removeAllViews();
        for (int i = 0; i < count; i++) {
            TextView textView = new TextView(getContext());
            textView.setTextSize(textSize);
            textView.setText(mDatas.get(i));
            textView.setTextColor(textColor);
            textView.setGravity(Gravity.CENTER);
            textView.setRotationX(45);
            addView(textView, new LayoutParams(350, 150));
        }
    }

    private float startY;
    private long pressTime;
    private float pressY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
//        boolean flag = detector.onTouchEvent(event);
        boolean flag = true;

        if (velocityTracker == null) {
            velocityTracker = VelocityTracker.obtain();
        }
        velocityTracker.addMovement(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.forceFinished(true);
                }
                pressY = startY = event.getY();
                pressTime = System.currentTimeMillis();
                break;
            case MotionEvent.ACTION_MOVE:
                scrollBy(0, (int) (startY - event.getY()));
                startY = event.getY();
                reSetTextView();
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP://抬起手指

//                if (Math.abs(pressY - event.getY()) / ((System.currentTimeMillis() - pressTime) / 1000) > 200) {//快速滑动
//                    Log.i("syso", "快速滑动...........");
//                    mScroller.startScroll(0, getScrollY(), 0, mHeight - getScrollY(), 1000);
//                } else {
//                scrollToItem();
//                }

                velocityTracker.computeCurrentVelocity(1000);
                int vY = (int) velocityTracker.getYVelocity();
                if (vY < -SNAP_VELOCITY) {//向上
                    scrollToBottom();
                } else if (vY > SNAP_VELOCITY) {//向下
                    scrollToTop();
                } else {
                    scrollToItem();
                }

                if (velocityTracker != null) {
                    velocityTracker.clear();
                    velocityTracker.recycle();
                    velocityTracker = null;
                }
                break;
        }
        return flag;
    }

    /**
     * 滚动到指定项(选中项)
     * 居中的为选中项
     */
    private void scrollToItem() {
        int scrollY = getScrollY();
        int cellH = getChildAt(0).getMeasuredHeight();
        int topIndex = scrollY / cellH;
        mSelectedItemIndex = scrollY % cellH / (float) cellH > 0.5f ? topIndex + 1 : topIndex;
        if (mSelectedItemIndex < 0) {
            mSelectedItemIndex = 0;
        }
        if (mSelectedItemIndex > mDatas.size() - 1) {
            mSelectedItemIndex = mDatas.size() - 1;
        }

        int dy = mSelectedItemIndex * getChildAt(0).getMeasuredHeight() - getScrollY();
        mScroller.startScroll(0, getScrollY(), 0, dy, 500);
        postInvalidate();
    }

    /**
     * 设置选中项
     *
     * @param position
     */
    public void setSelectedPosition(int position, boolean isScrolling) {
        if (position < 0) {
            position = 0;
        }
        if (position > mDatas.size() - 1) {
            position = mDatas.size() - 1;
        }
        this.mSelectedItemIndex = position;

        int dy = position * getChildAt(0).getMeasuredHeight() - getScrollY();
        if (isScrolling) {
            mScroller.startScroll(0, getScrollY(), 0, dy, 500);
            postInvalidate();
        } else {
            scrollTo(0, getScrollY() + dy);
            postInvalidate();
        }
    }

    /**
     * 滚动到顶部
     */
    private void scrollToTop() {
        mScroller.startScroll(0, getScrollY(), 0, -getScrollY(), 1000);
        postInvalidate();
    }

    /**
     * 滚动到底部
     */
    private void scrollToBottom() {
        mScroller.startScroll(0, getScrollY(), 0, mHeight - getScrollY() - getMeasuredHeight(), 1000);
        postInvalidate();
    }

    @Override
    public void computeScroll() {
//        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            this.scrollTo(0, mScroller.getCurrY());
            reSetTextView();
            postInvalidate();
        }
    }

    private void reSetTextView() {
        //找出当前显示的View,关键：求出先对屏幕的TOPView.Top - ScroolY
        //默认dy >= 0
        int dy = getScrollY();
        int cellH = getChildAt(0).getMeasuredHeight();
        int visiCount = dy % cellH == 0 ? mVisibCount : mVisibCount + 1;//显示个数

        int index = dy / cellH;
        for (int i = 0; i < visiCount; i++) {
            if (index + i <= getChildCount()) {
                TextView child = (TextView) getChildAt(index - 1 + i);
                if (child != null) {
                    child.setTextSize(textSize * Math.max(0.6f, 1 - Math.abs(child.getTop() - dy - cellH) / (float) cellH));
                    child.setAlpha(1.0f * Math.max(0.5f, 1 - Math.abs(child.getTop() - dy - cellH) / (float) cellH));
                    child.setRotationX(mRatioX * (child.getTop() - dy - cellH) / (float) cellH);
                }
            }
        }

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();

        int top = 0;
        int h = 0;
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
            h = view.getMeasuredHeight();
            top += h;
            view.layout(0, top, view.getMeasuredWidth(), top + h);
        }

        reSetTextView();
//        setSelectedPosition(mSelectedItemIndex,false);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    /**
     * 测量容器高度
     *
     * @param heightMeasureSpec
     * @return
     */
    private int measureHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = 0;
        switch (mode) {
            case MeasureSpec.EXACTLY:
                size = MeasureSpec.getSize(heightMeasureSpec);
                mHeight = (mDatas.size() + 2) * getChildAt(0).getMeasuredHeight();
                if (mDatas.size() < mVisibCount) {//显示可是可数
                    mHeight = mVisibCount * getChildAt(0).getMeasuredHeight();
                }
                break;
            case MeasureSpec.AT_MOST:
                int count = mDatas.size();//显示全部
                mHeight = (count + 2) * getChildAt(0).getMeasuredHeight();
                if (count > mVisibCount) {//显示可是可数
                    count = mVisibCount;
                } else {
                    mHeight = mVisibCount * getChildAt(0).getMeasuredHeight();
                }
                for (int i = 0; i < count; i++) {
                    size += getChildAt(i).getMeasuredHeight();
                }
                break;
        }
        return size;
    }

    /**
     * 测量容器宽度
     *
     * @param widthMeasureSpec
     * @return
     */
    private int measureWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = 0;
        switch (mode) {
            case MeasureSpec.EXACTLY:
                size = MeasureSpec.getSize(widthMeasureSpec);
                break;
            case MeasureSpec.AT_MOST:
                int width = 0;
                int count = getChildCount();
                for (int i = 0; i < count; i++) {
                    width = getChildAt(i).getMeasuredWidth();
                    if (width > size) {
                        size = width;
                    }
                }
                break;
        }
        return size;
    }

    public void bindDatas(List<String> mDatas) {
//        this.mDatas = mDatas;
        if (mDatas == null) {
            return;
        }
        this.mDatas.clear();
        this.mDatas.addAll(mDatas);
        init();
    }

    /**
     * 获取选中项下标
     *
     * @return
     */
    public int getSelectedItemIndex() {
        return mSelectedItemIndex;
    }

    public void setSelectedItemIndex(int position) {
        this.mSelectedItemIndex = position;
    }

    /**
     * 角度
     *
     * @param angle
     */
    public void setRatioX(float angle) {
        this.mRatioX = angle;
    }

    /**
     * 文字大小
     *
     * @param textSize
     */
    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    /**
     * 文字颜色
     *
     * @param color
     */
    public void setTextColor(@ColorInt int color) {
        this.textColor = color;
    }

    private GestureDetector.OnGestureListener gestureListener = new GestureDetector.OnGestureListener() {
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public void onShowPress(MotionEvent e) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            scrollBy(0, (int) distanceY);
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {

        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    };
}
